#ifndef KEYBICON_H
#define KEYBICON_H

#include "stdafx.h"

#include "keybdef.h"

#include <map>

class KB_Icon
{
public:
  KB_Icon()
  {
    iconUnknown = (HICON)LoadImage( NULL, TEXT("unknown.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
  }

  void loadIcons(const InputLayouts &layouts)
  {
    wchar_t filename[32] = {0};

    for (UINT i = 0; i < layouts.size(); i++)
    {
      HKL id = layouts.at(i).hkl;

      if (icons.find(id) != icons.end())
        continue;

      unsigned code = (unsigned)id;

      wsprintf(filename, TEXT("%x.ico\0"), code);
      HICON icon = (HICON)LoadImage( NULL, filename, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
      if (icon == NULL)
      {
        wsprintf(filename, TEXT("%x.ico\0"), code & 0xffff);
        icon = (HICON)LoadImage( NULL, filename, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
        if (icon == NULL)
        {
          // create an icon with 2 letters
          icon = createIconByCode(layouts.at(i).name.c_str());
          //	continue;
        }
      }

      icons[id] = icon;
    }

  }

  HICON HKL2HICON(HKL id)
  {
    if (icons.find(id) != icons.end())
      return icons[id];

    return iconUnknown;
  }

  //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  //
  // BitmapToIcon
  //
  static HRESULT BitmapToIcon(HDC hdcRef, HBITMAP hBitmap, COLORREF crTransparent, HICON *phIcon)
  {
    HRESULT hr;
    ICONINFO ii;
    HICON hIcon;

    if( phIcon )
    {
      *phIcon = NULL;
      hr = _BitmapToIconInfo(hdcRef, hBitmap, crTransparent, &ii );

      if( SUCCEEDED( hr ) )
      {
        hIcon = CreateIconIndirect(&ii);

        DeleteObject((HGDIOBJ)ii.hbmMask);
        DeleteObject((HGDIOBJ)ii.hbmColor);

        *phIcon = hIcon;
        hr = S_OK;
      }
    }
    else
    {
      hr = E_POINTER;
    }

    return hr;
  }

private:
  HICON createIconByCode(const wchar_t *name)
  {
    HDC screenDevice = GetDC(0);
    HDC hdc = CreateCompatibleDC(screenDevice);
    ReleaseDC(0, screenDevice);

    BITMAPINFOHEADER bitmapInfo;
    bitmapInfo.biSize        = sizeof(BITMAPINFOHEADER);
    bitmapInfo.biWidth       = 16;
    bitmapInfo.biHeight      = 16;
    bitmapInfo.biPlanes      = 1;
    bitmapInfo.biBitCount    = 32;
    bitmapInfo.biCompression = BI_RGB;
    bitmapInfo.biSizeImage   = 0;
    bitmapInfo.biXPelsPerMeter = 0;
    bitmapInfo.biYPelsPerMeter = 0;
    bitmapInfo.biClrUsed       = 0;
    bitmapInfo.biClrImportant  = 0;
    DWORD* bits;

    HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
    HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);

    HFONT fnt = CreateFont(16,5,0,0,0,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
      ANTIALIASED_QUALITY,FF_DONTCARE,TEXT("Verdana"));
    SelectObject(hdc, fnt);

    RECT rect = {0,0,16,16};
    FillRect(hdc, &rect, (HBRUSH) (WHITE_BRUSH));

	SetBkMode(hdc, OPAQUE);
	SetTextColor(hdc,0x00006600);

    /*int a = */DrawText(hdc,name,2,&rect,DT_CENTER | DT_VCENTER);

    HICON icon;
    /*HRESULT r = */BitmapToIcon(hdc, winBitmap, 0xffffffff, &icon);

    // cleanup
    SelectObject(hdc, oldhdc); //restore state
    DeleteObject(winBitmap);
    DeleteObject(fnt);
    DeleteDC(hdc);

    return icon;
  }

  //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  //
  // _BitmapToIconInfo
  //  winapi.net
  //
  static HRESULT _BitmapToIconInfo(HDC hdcRef, HBITMAP hBmpSrc, COLORREF crTransparent, ICONINFO* pii)
  {
    COLORREF crBkgnd, crText;
    BITMAP   bm;
    HDC      hdc1, hdc2;

    GetObject(hBmpSrc, sizeof(bm), &bm);

    hdc1 = CreateCompatibleDC(hdcRef);
    hdc2 = CreateCompatibleDC(hdcRef);
    pii->fIcon    = TRUE;
    pii->xHotspot = 0;
    pii->yHotspot = 0;
    pii->hbmMask  = (HBITMAP)SelectObject(hdc1, CreateBitmap(bm.bmWidth,
      bm.bmHeight, 1, 1, NULL));
    pii->hbmColor = (HBITMAP)SelectObject(hdc2, CopyImage(hBmpSrc, IMAGE_BITMAP,
      bm.bmWidth, bm.bmHeight, 0));
    crBkgnd = SetBkColor(hdc2, crTransparent );

    BitBlt(hdc1, 0, 0, bm.bmWidth, bm.bmHeight, hdc2, 0, 0, SRCCOPY);

    SetBkColor(hdc2, RGB(0x00, 0x00, 0x00));
    crText = SetTextColor(hdc2, RGB(0xFF, 0xFF, 0xFF));

    BitBlt(hdc2, 0, 0,
      bm.bmWidth, bm.bmHeight, hdc1, 0, 0, SRCAND);

    SetTextColor(hdc2, crText);
    SetBkColor(hdc2, crBkgnd);

    pii->hbmColor = (HBITMAP)SelectObject(hdc2, pii->hbmColor);
    pii->hbmMask  = (HBITMAP)SelectObject(hdc1, pii->hbmMask);

    DeleteDC(hdc2);
    DeleteDC(hdc1);

    return S_OK;
  }

  std::map<HKL,HICON> icons;
  HICON iconUnknown;
};

#endif
